/*******************************************************************************
 *
 *    Copyright (c) Baina Info Tech Co. Ltd
 *
 *    Snappy
 * 
 *    ArrayUtils
 *
 *    @author: chzhong
 *    @since:  2010-6-9
 *    @version: 1.0
 *
 ******************************************************************************/

package com.sdk.util;

import java.lang.reflect.Array;
import java.util.ArrayList;

import android.text.TextUtils;

public final class ArrayUtils {

    /**
     * Join an array's item's string representation with specified separator.
     * @param <T> the type of the item.
     * @param array the array.
     * @param separator the separator. If the separator is null,  empty string will be used.
     * @return A string with all items in {@code array}, separated by {@code  separator}.
     */
    public static <T> String join(final T[] array, String separator) {
        if (null == separator) {
            separator = "";
        }
        if (null == array || 0 == array.length) {
            return "";
        }
        final StringBuilder sb = new StringBuilder();
        for (final T item : array) {
            sb.append(item);
            sb.append(separator);
        }
        if (separator.length() > 0 && sb.length() > separator.length()) {
            sb.delete(sb.length() - separator.length(), sb.length());
        }
        return sb.toString();
    }


    /**
     * Determine the position of an element in an array.
     * @param <T> the type of the element.
     * @param array the array.
     * @param s the element.
     * @return the index of {@code s} in {@code array}, or -1 if not found.
     */
    public static <T> int indexOf(final T[] array, final T s) {
        if (null == array) {
            return -1;
        }
        for (int i = 0; i < array.length; i++) {
            if (array[i].equals(s)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Determine whether specified array contains a certain object.
     * @param <T> the type of the array item.
     * @param array the array to check.
     * @param object the object to compare.
     * @return true if {@code array} contains {@code object}, false otherwise.
     */
    public static final <T> boolean contains(final T[] array, final T object) {
        if (null == array) {
            return false;
        }
        final int length = array.length;
        for (int i = 0; i < length; ++i) {
            final T element = array[i];
            if (element == object || (object != null && object.equals(array[i]))) {
                return true;
            }
        }
        return false;
    }

    /**
     * Determine whether the specified array contains a specified text.
     * @param array the array to check.
     * @param text the text to compare.
     * @return true if {@code array} contains {@code text}, false otherwise.
     */
    public static final boolean contains(final String[] array, final String text) {
        if (null == array) {
            return false;
        }
        final boolean isTextEmpty = TextUtils.isEmpty(text);
        final int length = array.length;
        for (int i = 0; i < length; ++i) {
            final String element = array[i];
            if ((isTextEmpty &&  TextUtils.isEmpty(element)) || (!isTextEmpty && text.equals(element))) {
                return true;
            }
        }
        return false;
    }

    /**
     * Determine whether the specified array contains a specified text. Using case insensitive comparasion.
     * @param array the array to check.
     * @param text the text to compare.
     * @return true if {@code array} contains {@code text}, false otherwise.
     */
    public static final boolean containsIgnoreCase(final String[] array, final String text) {
        if (null == array) {
            return false;
        }
        final boolean isTextEmpty = TextUtils.isEmpty(text);
        final int length = array.length;
        for (int i = 0; i < length; ++i) {
            final String element = array[i];
            if ((isTextEmpty &&  TextUtils.isEmpty(element)) || (!isTextEmpty && text.equalsIgnoreCase(element))) {
                return true;
            }
        }
        return false;
    }

    /**
     * Set all elements in an array to null.
     * @param array the array to clear.
     */
    public static final <T> void clear(final T[] array) {
        if (null == array) {
            return;
        }
        final int length = array.length;
        for (int i = 0; i < length; i++) {
            array[i] = null;
        }
    }


    /**
     * Remove all null items in an array.
     * @param array the array to normalize. If you pass {@code null}, an {@code null} will return.
     */
    @SuppressWarnings("unchecked")
    public static final <T> T[] normalize(final T[] array) {
        if (null == array) {
            return (T[])new Object[0];
        }
        final int length = array.length;
        final ArrayList<T> list = new ArrayList<T>();
        for (int i = 0; i < length; i++) {
            final T item = array[i];
            if (item != null) {
                list.add(item);
            }
        }
        final Class<?> ct = array.getClass().getComponentType();
        T[] normalizedItems = (T[])Array.newInstance(ct, list.size());
        normalizedItems = list.toArray(normalizedItems);
        return normalizedItems;
    }


    /**
     * Remove all null or empty strings in an array.
     * @param array the array to normalize. If you pass {@code null}, an  empty array will be returned.
     */
    public static final String[] normalize(final String[] array) {
        if (null == array) {
            return new String[0];
        }
        final int length = array.length;
        final ArrayList<String> list = new ArrayList<String>();
        for (int i = 0; i < length; i++) {
            final String item = array[i];
            if (!TextUtils.isEmpty(item) && !TextUtils.isEmpty(item.trim())) {
                list.add(item);
            }
        }
        String[] normalizedItems = new String[list.size()];
        normalizedItems = list.toArray(normalizedItems);
        return normalizedItems;
    }

}
